#include "vec3.h"

vec3::vec3()
:x(0),y(0),z(0)
{
}

vec3::vec3(float x_,float y_,float z_)
:x(x_),y(y_),z(z_)
{
}

vec3::vec3(float value)
:x(value),y(value),z(value)
{
}

vec3::vec3(const vec3 &copy)
:x(copy.x),y(copy.x),z(copy.x)
{
}


inline vec3& vec3::operator =(const vec3 &other)
{
	x = other.x;
	y = other.y;
	z = other.z;

	return *this;
}

inline bool vec3::operator == (const vec3 &other) const
{
	return (x == other.x) && (y == other.y) && (z == other.z);
}

inline bool vec3::operator != (const vec3 &other) const
{
	return (x != other.x) || (y != other.y) || (z != other.z);
}

inline vec3 vec3::operator +(const vec3 &other) const
{
	return vec3(x + other.x, y + other.y, z + other.z);
}

inline vec3 vec3::operator +(float value) const
{
	return vec3(x + value, y + value, z+ value);
}

inline vec3 vec3::operator *(const vec3 &other) const
{
	return vec3(x * other.x, y * other.y, z * other.z);
}

inline vec3 vec3::operator *(float value) const
{
	return vec3(x * value, y * value, z * value);
}


inline vec3& vec3::operator +=(const vec3 &other)
{
	x+=other.x;
	y+=other.y;
	z+=other.z;

	return *this;
}

inline vec3& vec3::operator +=(float value)
{
	x+=value;
	y+=value;
	z+=value;

	return *this;
}

inline vec3& vec3::operator *=(const vec3 &other)
{
	x*=other.x;
	y*=other.y;
	z*=other.z;

	return *this;
}

inline vec3& vec3::operator *=(float value)
{
	x*=value;
	y*=value;
	z*=value;

	return *this;
}


inline vec3 vec3::operator -(const vec3 &other) const
{
	return vec3(x - other.x, y - other.y, z - other.z);
}

inline vec3 vec3::operator -(float value) const
{
	return vec3(x - value, y - value, z - value);
}

inline vec3 vec3::operator /(const vec3 &other) const
{
	return vec3(x / other.x, y / other.y, z / other.z);
}

inline vec3 vec3::operator /(float value) const
{
	return vec3(x / value, y / value, z / value);
}


inline vec3& vec3::operator -=(const vec3 &other)
{
	x -= other.x;
	y -= other.y;
	z -= other.z;

	return *this;
}

inline vec3& vec3::operator -=(float value)
{
	x -= value;
	y -= value;
	z -= value;

	return *this;
}

inline vec3& vec3::operator /=(const vec3 &other)
{
	x /= other.x;
	y /= other.y;
	z /= other.z;

	return *this;
}

inline vec3& vec3::operator /=(float value)
{
	x /= value;
	y /= value;
	z /= value;

	return *this;
}

inline vec3 vec3::operator +() const
{
	return vec3(x,y,z);
}

inline vec3 vec3::operator -() const
{
	return vec3(-x,-y,-z);
}



inline vec3::operator float*()
{
	return &x;
}

inline vec3::operator const float*() const
{
	return &x;
}

inline float vec3::operator [] (int index)
{
	return *(&x + index);
}

inline float vec3::len()
{
	return sqrt(x*x + y*y + z*x);
}

inline void vec3::normalize()
{
	float l = len();
	x /= l;
	y /= l;
	z /= l;
}

inline vec3 vec3::lerp(const vec3 &other, float scalar) const
{
	return vec3(x + (other.x - x) * scalar
		,y + (other.y - y) * scalar
		,z + (other.z - z) * scalar);
}

inline void vec3::lerpme(const vec3 &other, float scalar)
{
	x += (other.x - x) * scalar;
	y += (other.y - y) * scalar;
	z += (other.z - z) * scalar;
}

float vec3::dot(const vec3& other)
{
	return x * other.x + y * other.y + z * other.z;
}

vec3 vec3::cross(const vec3& other)
{
	vec3 result;

	result.x= y * other.z - z * other.y;
	result.y= z * other.x - x * other.z;  
	result.z= x * other.y - y * other.x;

	return result;
}
